package com.gydz.gydzbaseframeworkboot.CsdE.domain;

import com.gydz.gydzbaseframeworkboot.Common.utils.page.PageParam;
import com.gydz.gydzbaseframeworkboot.CsdE.controller.EInterfaceCsdCallRecController;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.format.annotation.DateTimeFormat;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@EqualsAndHashCode(callSuper = true)
@Data
public class EInterfaceCsd extends PageParam {

    // 序号
    private Long DataNum;

    // 触发时间
    private Date RecTime;

    // MSISDN
    private Long MsIsdn;

    // IMSI
    private Long IMSI;

    // 机车号
    private String LocoNum;

    // CTCS_ID
    private Long CtcsId;

    // 车次
    private String TrainNum;

    // RBC号码
    private Long RbcNum;

    // 线路
    private String LineName;

    // 小区
    private String LacCiName;

    // 公里标
    private Long Kilo;

    // 传送方向
    private Integer DataDir;

    // CRC校验
    private Integer CRC;

    // 数据类型
    private Integer C3DataType;

    // 链路层
    private Long HdlcMsgType;

    // 网络层
    private Long NpduMsgType;

    // 传输层
    private Long TpduMsgType;

    // 安全层
    private Long SapduMsgType;

    // 应用层
    private Long ApduMsgType;

    // 发送T_Train
    private Long ApduTTrain;

    // 确认T_Train
    private Long ApduTTrainCfm;

    // 上行帧序号
    private Integer HdlcNs;

    // 下行帧序号
    private Integer HdlcNr;

    // RR帧类型
    private Integer HdlcPF;

    // 拆链原因
    private Integer Q931ReleaseCause;

    // LRBG
    private String LRBGIDName;

    // 速度(km/h)
    private Long Speed;

    // 运行模式
    private Integer C3Mode;

    // 设备号
    private Integer DevNum;

    // 端口号
    private Integer PortNum;

    // 时隙号
    private Integer SlotNum;

    // 子时隙号
    private Integer SubSlotNum;

    // 数据长度
    private Long DataLen;

    // 数据内容
    private String DataContent;

    // PRI口索引号
    private Long CdrIndexPri;

    // ====================================================================================================

    private Long CdrIndexCsd;

    private Integer BureauNum;

    private String RbcName;

    private String LacCi;

    private String FrameType;

    private Integer HdlcAddr;

    private Integer FrmrW;

    private Integer FrmrX;

    private Integer FrmrY;

    private Integer FrmrZ;

    private Integer NpduMore;

    private Long TpduSrcDef;

    private Long TpduDstDef;

    private Long TpduNr;

    private Long TpduEot;

    private Long TpduRoa;

    private Long SapduCause;

    private Long SapduSubCause;

    private Integer ApduM24HaveChgClass;

    private Long ApduMLevel;

    private Long ApduMMode;

    private Integer ApduHavePacket9;

    private Integer ApduHavePacket3DL;

    private Integer ApduHavePacket131DL;

    private Long ApduMAck;

    private Long ApduTNvContact;

    private Long ApduNidRadio;

    private Long ApduNidRbc;

    private Long TpduCause;

    private Long Q931CallRef;

    private Long LRBGID;

    private String ApduDataContent;

    private Long HdlcCmdType;

    private Integer KiloDir;

    private Integer ApduHavePacket42;

    private Long ApduPacket4MError;

    private Long Cic;

    private Integer V110Status;

    private Long CsdId;

    /**
     * 开始时间
     */
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date startTime;

    /**
     * 结束时间
     */
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date endTime;

    /// 转换后字段（添加在类末尾）
    private String dataDirStr;          // 方向描述
    private String crcStr;              // CRC校验结果
    private String c3ModeStr;           // 列控等级
    private String c3DataTypeStr;       // 数据层级
    private String hdlcMsgTypeStr;      // HDLC帧类型
    private String npduMsgTypeStr;      // 网络层类型
    private String tpduMsgTypeStr;      // 传输层类型
    private String sapduMsgTypeStr;     // 安全层类型
    private String apduMsgTypeStr;      // 应用层类型
    private String hdlcPFStr;           // P/F标志描述
    private String tpduCauseStr;        // TPDU释放原因
    private String sapduCauseStr;       // SAPDU释放原因
    private String apduMLevelStr;       // CTCS等级
    private String apduMModeStr;        // 运行模式
    private String q931ReleaseCauseStr; // Q931拆链原因
    private String kiloDirStr;          // 公里标方向
    private String v110StatusStr;       // V110同步状态
    private String hdlcCmdTypeStr;      // HDLC命令类型
    private String q931CauseStr;        //q931CauseStr
    private String frameTypeStr;


    public void convertEnums() {
        this.dataDirStr = convertDataDir(this.DataDir);
        this.crcStr = convertCRC(this.CRC);
        this.c3ModeStr = convertC3Mode(this.C3Mode);
        this.c3DataTypeStr = convertC3DataType(this.C3DataType);
        this.hdlcMsgTypeStr = convertHdlcMsgType(this.HdlcMsgType);
        this.hdlcCmdTypeStr = convertHdlcCmdType(this.HdlcCmdType);
        this.tpduMsgTypeStr = convertTpduMsgType(this.TpduMsgType);
        this.sapduMsgTypeStr = convertSapduMsgType(this.SapduMsgType);
        this.v110StatusStr = convertV110Status(this.V110Status);
        this.kiloDirStr = convertKiloDir(this.KiloDir);
        this.q931CauseStr = convertQ931Cause(this.Q931ReleaseCause);
        this.apduMLevelStr = convertApduMLevel(this.ApduMLevel);
        this.apduMModeStr = convertApduMMode(this.ApduMMode);
        this.npduMsgTypeStr = convertNpduMsgType(this.NpduMsgType);
    }

    private String convertDataDir(Integer dir) {
        if (dir == null) return "";
        switch (dir) {
            case 0:
                return "MSC_TO_RBC";
            case 1:
                return "RBC_TO_MSC";
            case 2:
                return "OBC_TO_RBC";
            case 3:
                return "RBC_TO_OBC";
            default:
                return "未知方向";
        }
    }

    private String convertCRC(Integer crc) {
        return crc != null ? (crc == 0 ? "正确" : "错误") : "";
    }

    private String convertC3Mode(Integer mode) {
        if (mode == null) return "";
        switch (mode) {
            case 2:
                return "CTCS-2级";
            case 3:
                return "CTCS-3级";
            default:
                return "未知模式";
        }
    }

    private String convertC3DataType(Integer type) {
        if (type == null) return "";
        switch (type) {
            case 0:
                return "HDLC层";
            case 1:
                return "网络层";
            case 2:
                return "传输层";
            case 3:
                return "安全层";
            case 4:
                return "应用层";
            case 9:
                return "物理层";
            case 255:
                return "其他";
            default:
                return "未知类型";
        }
    }

    private String convertHdlcMsgType(Long type) {
        if (type == null) return "";
        switch (type.intValue()) {
            case 0x0:
                return "I_FRAME";
            case 0x1:
                return "S_FRAME";
            case 0x3:
                return "U_FRAME";
            default:
                return "未知帧类型";
        }
    }

    // 枚举映射表（在类中静态初始化）
    private static final Map<Integer, String> Q931_CAUSE_CODE_VALS = new HashMap<>() {{
        put(0x00, "Call successful");
        put(0x01, "Unallocated (unassigned) number");
        put(0x02, "No route to specified transit network");
        put(0x03, "No route to destination");
        put(0x04, "Send special information tone");
        put(0x05, "Misdialled trunk prefix");
        put(0x06, "Channel unacceptable");
        put(0x07, "Call awarded and being delivered in an established channel");
        put(0x08, "Prefix 0 dialed but not allowed");
        put(0x09, "Prefix 1 dialed but not allowed");
        put(0x0A, "Prefix 1 dialed but not required");
        put(0x0B, "More digits received than allowed, call is proceeding");
        put(0x10, "Normal call clearing");
        put(0x11, "User busy");
        put(0x12, "No user responding");
        put(0x13, "No answer from user (user alerted)");
        put(0x14, "Subscriber absent");
        put(0x15, "Call rejected");
        put(0x16, "Number changed");
        put(0x17, "Reverse charging rejected");
        put(0x18, "Call suspended");
        put(0x19, "Call resumed");
        put(0x1A, "Non-selected user clearing");
        put(0x1B, "Destination out of order");
        put(0x1C, "Invalid number format (incomplete number)");
        put(0x1D, "Facility rejected");
        put(0x1E, "Response to STATUS ENQUIRY");
        put(0x1F, "Normal unspecified");
        put(0x21, "Circuit out of order");
        put(0x22, "No circuit/channel available");
        put(0x23, "Destination unattainable");
        put(0x25, "Degraded service");
        put(0x26, "Network out of order");
        put(0x27, "Transit delay range cannot be achieved");
        put(0x28, "Throughput range cannot be achieved");
        put(0x29, "Temporary failure");
        put(0x2A, "Switching equipment congestion");
        put(0x2B, "Access information discarded");
        put(0x2C, "Requested circuit/channel not available");
        put(0x2D, "Pre-empted");
        put(0x2E, "Precedence call blocked");
        put(0x2F, "Resources unavailable, unspecified");
        put(0x31, "Quality of service unavailable");
        put(0x32, "Requested facility not subscribed");
        put(0x33, "Reverse charging not allowed");
        put(0x34, "Outgoing calls barred");
        put(0x35, "Outgoing calls barred within CUG");
        put(0x36, "Incoming calls barred");
        put(0x37, "Incoming calls barred within CUG");
        put(0x38, "Call waiting not subscribed");
        put(0x39, "Bearer capability not authorized");
        put(0x3A, "Bearer capability not presently available");
        put(0x3E, "Inconsistency in designated outgoing access information and subscriber class");
        put(0x3F, "Service or option not available, unspecified");
        put(0x41, "Bearer capability not implemented");
        put(0x42, "Channel type not implemented");
        put(0x43, "Transit network selection not implemented");
        put(0x44, "Message not implemented");
        put(0x45, "Requested facility not implemented");
        put(0x46, "Only restricted digital information bearer capability is available");
        put(0x4F, "Service or option not implemented, unspecified");
        put(0x51, "Invalid call reference value");
        put(0x52, "Identified channel does not exist");
        put(0x53, "Call identity does not exist for suspended call");
        put(0x54, "Call identity in use");
        put(0x55, "No call suspended");
        put(0x56, "Call having the requested call identity has been cleared");
        put(0x57, "Called user not member of CUG");
        put(0x58, "Incompatible destination");
        put(0x59, "Non-existent abbreviated address entry");
        put(0x5A, "Destination address missing, and direct call not subscribed");
        put(0x5B, "Invalid transit network selection (national use)");
        put(0x5C, "Invalid facility parameter");
        put(0x5D, "Mandatory information element is missing");
        put(0x5F, "Invalid message, unspecified");
        put(0x60, "Mandatory information element is missing");
        put(0x61, "Message type non-existent or not implemented");
        put(0x62, "Message not compatible with call state or message type non-existent or not implemented");
        put(0x63, "Information element non-existent or not implemented");
        put(0x64, "Invalid information element contents");
        put(0x65, "Message not compatible with call state");
        put(0x66, "Recovery on timer expiry");
        put(0x67, "Parameter non-existent or not implemented - passed on");
        put(0x6E, "Message with unrecognized parameter discarded");
        put(0x6F, "Protocol error, unspecified");
        put(0x7F, "Internetworking, unspecified");
        put(0xFF, "Non-specific failure");
    }};

    private static final Map<Integer, String> APDU_M_MODE_VALS = new HashMap<>() {{
        put(0, "完全监督模式");
        put(1, "引导模式");
        put(2, "目视行车模式");
        put(3, "调车模式");
        put(5, "休眠模式");
        put(6, "待机模式");
        put(7, "冒进防护模式");
        put(8, "冒进后防护模式");
        put(9, "系统故障模式");
        put(10, "隔离模式");
        put(13, "SN模式");
        put(14, "退行模式");
    }};

    private String convertNpduMsgType(Long type) {

        return type != null ? "网络层类型" + type : "";
    }

    private String convertTpduMsgType(Long type) {
        if (type == null) return "";
        switch (type.intValue()) {
            case 0xE0:
                return "TPDU_CR";
            case 0xD0:
                return "TPDU_CC";
            case 0x80:
                return "TPDU_DR";
            case 0xC0:
                return "TPDU_DC";
            case 0xF0:
                return "TPDU_DT";
            case 0x60:
                return "TPDU_AK";
            case 0x70:
                return "TPDU_ER";
            default:
                return "未知传输层类型(0x" + Integer.toHexString(type.intValue()) + ")";
        }
    }

    private String convertSapduMsgType(Long type) {
        if (type == null) return "";
        switch (type.intValue()) {
            case 0x01:
                return "SAPUD_AU1";
            case 0x02:
                return "SAPUD_AU2";
            case 0x03:
                return "SAPUD_AU3";
            case 0x09:
                return "SAPUD_AR";
            case 0x05:
                return "SAPUD_DT";
            case 0x08:
                return "SAPUD_DI";
            case 0x0B:
                return "SAPUD_RQ";
            case 0x0C:
                return "SAPUD_RP";
            default:
                return "未知安全层类型(0x" + Integer.toHexString(type.intValue()) + ")";
        }
    }

    private String convertApduMLevel(Long level) {
        if (level == null) return "";
        switch (level.intValue()) {
            case 1:
                return "CTCS-2级";
            case 3:
                return "CTCS-3级";
            case 4:
                return "CTCS-4级";
            default:
                return "未知等级(" + level + ")";
        }
    }

    private String convertApduMMode(Long mode) {
        return APDU_M_MODE_VALS.getOrDefault(mode != null ? mode.intValue() : -1, "未知模式(" + mode + ")");
    }

    private String convertQ931Cause(Integer cause) {
        return Q931_CAUSE_CODE_VALS.get(cause);
    }

    private String convertKiloDir(Integer dir) {
        if (dir == null) return "";
        return dir == 0 ? "增加" : "减少";
    }

    private String convertV110Status(Integer status) {
        return status != null ? (status == 0 ? "不同步" : "同步") : "";
    }

    private String convertHdlcCmdType(Long type) {
        if (type == null) return "";
        switch (type.intValue()) {
            case 0:
                return "I";
            case 1:
                return "RR";
            case 5:
                return "RNR";
            case 9:
                return "REJ";
            case 13:
                return "SREJ";
            case 63:
                return "SABME";
            case 35:
                return "DISC";
            case 15:
                return "DM";
            case 51:
                return "UA";
            case 71:
                return "FRMR";
            case 3:
                return "UI";
            default:
                return "";
        }
    }

}
